package tutorial

import java.io.PrintWriter

/**
 *
 * zhu.tan@gmail.com
 * Date: Aug 10, 2010
 */

object usingFun {

  def using[A, B <: {def close() : Unit}](closeable: B)(f: B => A): A =
    try {f(closeable)} finally {closeable.close()}

  using(new PrintWriter("sample.txt")) {
    out =>
      out.println("hellow world!")
  }
}



object UsingTest {
  type Closeable = {def close(): Unit}

  final class CloseAfter[A <: Product](val x: A) {
    def closeAfter[B](block: A => B): B = {
      try {
        block(x);
      } finally {
        for (i <- 0 until x.productArity) {
          x.productElement(i) match {
            case c: Closeable => println("closing " + c); c.close()
            case _ =>
          }
        }
      }
    }
  }

  implicit def any2CloseAfter[A <: Product](x: A): CloseAfter[A] =
    new CloseAfter(x)

  def main(args: Array[String]): Unit = {
    import java.io._

    (new BufferedReader(new FileReader("in.txt")),
            new PrintWriter("out.txt"),
            new PrintWriter("sample.txt")) closeAfter {
      case (in, out, other) =>
        out.println(in.readLine)
        other.println("hello world!")
    }
  }
}
